home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 326-350 / disk_348 / ilbmlib / iffinfo.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  11KB  |  342 lines

  1. /* Ilbm.library C application, PicInfo.c:
  2.  
  3.     Set your editor's TAB width to 3
  4.  
  5.     cc +p IFFinfo.c
  6.     as -cd IlbmInterface.asm
  7.     ln -o IFFinfo IFFinfo.o IlbmInterface.o -lcl32
  8.  
  9.     This program can only be run from the CLI. It takes 1 arg, the name of a
  10. file. This program will then print information about the file. For ILBMs and
  11. ANIMs, it will print out information from the BHMD(s) such as image width,
  12. height, depth, etc.  For other IFF files, it will simply print the chunk IDs
  13. as it encounters them.  For ANIMs, it will total the number of "frames"
  14. (ILBMs) in the file.  Note that the library automatically dives into LISTS
  15. and CATS on our behalf.  We don't even have to know that we are inside of a
  16. LIST or CAT.
  17.  
  18. This is an example of using the library's mid-level routine LoadILBM() with
  19. our own FORM and PROP handlers instead of lib's default routines. This is the
  20. way to go if you need an ANIM reader or some non-ILBM reader/writer. Note
  21. that if our FORMHandler wasn't interested in ILBMs or ANIMs, we wouldn't need
  22. an ILBMFrame, and would use LoadIFF() instead of LoadILBM().
  23.  
  24. */
  25.  
  26. #include "math.h"
  27. #include "functions.h"      /* Manx C declarations */
  28.  
  29. #include "exec/tasks.h"
  30. #include "exec/types.h"
  31. #include "exec/memory.h"
  32. #include "libraries/dos.h"
  33. #include "libraries/dosextens.h"
  34.  
  35.  /* The ilbm lib C INCLUDE file */
  36. #include "ILBM_Lib.h"
  37.  
  38.  
  39. /*-------------------------------defines---------------------------------*/
  40.  
  41. IFFP myForm();
  42. IFFP myProp();
  43.  
  44.  /* Data for the Dissidents ILBM library */
  45. struct ILBMBase    *ILBMBase=0L;
  46. struct ILBMFrame    myILBMFrame;   /* Whenever we plan on parsing an ILBM
  47.                                                 or ANIM, we need an ILBMFrame */
  48.  /* Data for our program */
  49. struct FileHandle   *fp = 0;
  50. SHORT  numFrames = -1;            /* To count the # of frames in an ANIM */
  51. UBYTE handled_anim = 0;            /* To tell main() that we found an ANIM */
  52.  
  53. /*------------------------------start of main()----------------------------*/
  54.  
  55. main( argc, argv )
  56. LONG argc;
  57. UBYTE *argv[];
  58. {
  59.     IFFP  Result;
  60.  /* LoadILBM() and LoadIFF() need a Vectors structure */
  61.     Vectors myVectors;
  62.  
  63.  /* We expect the filename for the first arg. */
  64.     if( argc != 2 )
  65.     {
  66.         printf("USAGE: IFFinfo filename\n");
  67.         exit();
  68.     }
  69.  
  70.  /* Open the ILBM lib */
  71.     if( (ILBMBase=(struct ILBMBase *)OpenLibrary("ilbm.library", 0L)) == NULL )
  72.     {
  73.         printf("Need the dissidents ilbm.library on boot disk\n");
  74.         exit();
  75.     }
  76.  
  77.  /* Note that we are using the lib's middle level functions so that we can
  78.      install our own handlers for each encountered group and context. Also,
  79.      we can parse any IFF FORM, not just ILBMs and ANIMs using this level.
  80.      Unlike the lib's high level ILBM functions LoadIFFToWindow() and
  81.      SaveWindowToIFF(), the mid level functions don't open the IFF file for us.
  82.      We are going to install our own function, myForm(), as the routine
  83.      which the library calls whenever it encounters a FORM ID. Our function,
  84.      myProp() will be called for non-ILBM PROPS. (Remember, the library
  85.      automatically handles all ILBM PROPS by parsing info into a PropILBMFrame.)
  86.      We "install" these routines by setting up the appropriate fields in our
  87.      Vectors structure. Let's do all this now. */
  88.  
  89.  /* Open the IFF File */
  90.     fp = Open( argv[1], MODE_OLDFILE );
  91.  
  92.     if (fp)
  93.     {
  94.  
  95.         /* Setup the Vectors structure. (i.e. "install" myForm() and myProp()) */
  96.         myVectors.PROPhandler = myProp;
  97.         myVectors.FORMhandler = myForm;
  98.         myVectors.CHUNKhandler = 0;
  99.         myVectors.NonILBMhandler = 0;
  100.         /* Don't care about CHUNKhandler or NonILBMhandler as long as we have
  101.             our own FORMhandler. */
  102.  
  103.         myILBMFrame.iUserFlags=0;
  104.  
  105.         /* Start parsing the file */
  106.         Result=LoadILBM( fp, &myVectors, &myILBMFrame );
  107.  
  108.         /* O.K. we're back. Did we successfully parse as much as we wanted?
  109.             Well, our FORM routine should have returned IFF_OKAY if we parsed
  110.             the entire file. Otherwise, myForm, myProp, or an internal library
  111.             routine knocked us out by returning some other IFFP error code. Let's
  112.             get an informative error msg to display.
  113.         */
  114.  
  115.          /* If some error, get the IFFP error message and print it */
  116.         if( Result != IFF_OKAY )
  117.         {
  118.             puts( GetIFFPMsg( Result ) );
  119.         }
  120.         else    /* If it was an ANIM we inspected, show the # of frames */
  121.         {
  122.             if( handled_anim )
  123.                 printf("Number of Frames = %d", numFrames+1);
  124.         }
  125.  
  126.         /* Close the IFF File */
  127.         Close(fp);
  128.  
  129.     }
  130.     else printf( "Couldn't open %s. \n", argv[1]);
  131.  
  132.     printf("\n");
  133.  
  134.  /* Close ILBM lib */
  135.     if( ILBMBase )        CloseLibrary( ILBMBase );
  136.     exit();
  137. }              /* end of main() */
  138.  
  139.  
  140. /*========= LoadILBM() or LoadIFF() calls me when it finds a FORM ==========*/
  141.  
  142. IFFP  myForm( chunkID, context, vectors, frame, proplist )
  143. PROPList *proplist;
  144. struct ILBMFrame *frame;
  145. Vectors *vectors;
  146. GroupContext *context;
  147. ID         chunkID;
  148. {
  149. register    IFFP   code = IFF_OKAY;
  150. register    ULONG  propf;
  151. BitMapHeader bmhdr;
  152.  
  153.     /* Print the FORM ID */
  154.     printf("========= FORM %c%c%c%c =========\n",
  155.                 (char) ((chunkID>>24L) & 0x7F),
  156.                 (char) ((chunkID>>16L) & 0x7F),
  157.                 (char) ((chunkID>>8) & 0x7F),
  158.                 (char) (chunkID & 0x7F) );
  159.  
  160. /* --------------------- ANIM HEADER ------------------------- */
  161.  
  162.     /* If an ANIM, reset our frame count and ANIM flags of iUserFlags.
  163.         Then parse the "frames" (imbedded ILBMs) of the ANIM. Note that
  164.         GetF1ChunkHdr actually calls our myForm() routine for each imbedded
  165.         ILBM "frame of animation" (i.e. this function is recursive). */
  166.  
  167.     if (chunkID == ID_ANIM)
  168.     {
  169.         /* set ANIMFLAG of iUserFlags to indicate that we're in an ANIM */
  170.         frame->iUserFlags |= ANIMFLAG;
  171.  
  172.         /* clear HANDLED_ANIM to indicate that we aren't successful yet */
  173.         handled_anim = 0;
  174.  
  175.         numFrames = -1;    /* first frame number will be 0 */
  176.  
  177.         /* Parse each frame of the ANIM */
  178.         while (code >= 0)
  179.         {
  180.             code = GetF1ChunkHdr(context);
  181.         }
  182.  
  183.         /* If we didn't get END_MARK back, then an error */
  184.         if (code == END_MARK)
  185.         {
  186.             /* set HANDLED_ANIM to indicate that we successfully handled the ANIM */
  187.             handled_anim = 1;
  188.  
  189.             code = IFF_OKAY;    /* So that we continue parsing any more FORMs in
  190.                                         the file */
  191.         }
  192.     }
  193.  
  194. /* ---------------------- ILBM FORMS (ANIM "frames") -------------------- */
  195.  
  196.     if (chunkID == ID_ILBM )
  197.     {
  198.         /* Parse an ILBM or an ANIM "frame" (which is also an ILBM) */
  199.  
  200.         /* If there was an ILBM PROP for this group, copy the PROPFrame to our
  201.             ILBMFrame.
  202.              Note: SearchPROP() can return any kind of frame. Here, it is an
  203.             ILBMFrame since chunkID == ID_ILBM. If we needed to reference
  204.             anything in the returned pointer, we would have to recast it as
  205.             an (ILBMFrame *).
  206.          */
  207.         if( !(propf = SearchPROP( chunkID, proplist )) )
  208.             CopyILBMProp( propf, frame );
  209.  
  210.         if( frame->iUserFlags & ANIMFLAG )
  211.             {
  212.             ++numFrames;        /* 1 more "frame" */
  213.             printf( "--- Frame #%d ---\n", numFrames+1 );
  214.             }
  215.  
  216.         while( code >= 0 )    /* Negative numbers are errors, 0 means "ok, continue"
  217.                                         and positive numbers are IFF chunk IDs
  218.                                      */
  219.  
  220.         {
  221.             /* Move to the start of the next chunk */
  222.             code = GetFChunkHdr( context );
  223.  
  224.             if (code > 0 )
  225.             /* Here's a chunk ID. If this were a REAL program, we'd probably
  226.                 check to see if this is a chunk that we want to parse. If so, we
  227.                 could get the chunksize from the context structure, read the chunk
  228.                 into memory, and do something with the data. For example, like
  229.                 what I did with the BMHD chunk. Or maybe like this:
  230.                         bytes = ChunkMoreBytes( context );
  231.                         if( !( memptr = AllocMem( bytes, 0L ) ))
  232.                         {
  233.                             code = IFFReadBytes( bytes, context, memptr );
  234.                         }
  235.  
  236.             */
  237.             {
  238.                 printf("     %c%c%c%c\n",
  239.                         (char) ( (code>>24L) & 0x7F),
  240.                         (char) ( (code>>16L) & 0x7F),
  241.                         (char) ( (code>>8) & 0x7F),
  242.                         (char) ( code & 0x7F) );
  243.  
  244.                 if( code == ID_BMHD )
  245.                 {
  246.                     /* Print out info about the image */
  247.                     code = GetBMHD(context, &bmhdr);
  248.                     if( code == IFF_OKAY )
  249.                     {
  250.                         printf("      width=%d, height=%d, depth=%d\n",
  251.                                      bmhdr.w, bmhdr.h, bmhdr.nPlanes);
  252.                     }
  253.                 }
  254.  
  255.             }
  256.         }
  257.     }
  258.  
  259. /* --------------------- Non-ILBM FORMS --------------------- */
  260.     else
  261.     {
  262.         /* A REAL program would normally search the PROPList for any frames
  263.             of the same type, and if found extract needed info from it.
  264.             See notes in myProp() */
  265.  
  266.         while( code >= 0 )
  267.         {
  268.             code = GetF1ChunkHdr(context);
  269.  
  270.             if (code > 0)
  271.             /* Here's a chunk ID. If this were a REAL program, we'd probably
  272.                 do something useful with it.
  273.             */
  274.             {
  275.                 printf("     %c%c%c%c\n",
  276.                         (char) ( (code>>24L) & 0x7F),
  277.                         (char) ( (code>>16L) & 0x7F),
  278.                         (char) ( (code>>8) & 0x7F),
  279.                         (char) ( code & 0x7F) );
  280.             }
  281.         }
  282.     }
  283.  
  284.     /*
  285.     As long as we rtn IFF_OKAY, the library will continue parsing the IFF 
  286.     file (until it gets to the end). If we rtn any other value, the library will
  287.     return us back to main() from LoadILBM() with that value. For example, if
  288.     we return IFF_DONE, we would return from LoadILBM with IFF_DONE.
  289.  
  290.     Note: the library routines GetFChunkHdr and GetF1ChunkHdr will return
  291.     END_MARK when there's no more chunks in this FORM. In that case, we should
  292.     know whether we found what we wanted in this FORM. If we did, we return
  293.     IFF_OKAY to continue parsing the next FORM (we may be inside of a LIST or
  294.     CAT), or IFF_DONE if we want to get out with what we've got. If we didn't
  295.     find what we want, we would return IFF_OKAY to continue parsing.
  296.  
  297.     In this example, we're looking for everything, so we always return IFF_OKAY
  298.     when GetFChunkHdr or GetF1ChunkHdr returns END_MARK.
  299.     */
  300.  
  301.     if (code == END_MARK)
  302.     {
  303.         /* Print a double-spaced line inbetween forms */
  304.         puts("=============================\n");
  305.         code = IFF_OKAY;
  306.     }
  307.  
  308.     return( code );
  309. }
  310.  
  311.  
  312. /*========= LoadILBM() or LoadIFF() calls me when it finds a PROP ==========*/
  313.  
  314. IFFP myProp( chunkID, propID, context, vectors, frame, proplist )
  315. PROPList *proplist;
  316. struct ILBMFrame *frame;
  317. Vectors *vectors;
  318. GroupContext *context;
  319. ID   propID;
  320. ID   chunkID;
  321. {
  322.     /* We only hear about non-ILBM PROPS. If this were a REAL program, we
  323.         would probably allocate some PROPFrame that we defined for the passed
  324.         propID (an SMUSPropFrame for an ID_SMUS maybe?).  Then we would
  325.         parse the PROP's chunks just like in the FORMhandler, storing info in
  326.         this new PROPFrame. Later, in our FORMHandler, we search the PROPList
  327.         for the appropriate ID and retrieve the info. The library automatically
  328.         updates the PROPList when it gets to the end of an IFF group so that you
  329.         don't have to keep track of which level you're at and which PROPS affect
  330.         which chunks. Also, the library frees all PROPFrames that you allocate
  331.         with GetPROPStruct() by the time we return to main. */
  332.  
  333.     /* Print the PROP ID */
  334.     printf("  PROP %c%c%c%c\n",
  335.                 (char) ((chunkID>>24L) & 0x7F),
  336.                 (char) ((chunkID>>16L) & 0x7F),
  337.                 (char) ((chunkID>>8) & 0x7F),
  338.                 (char) (chunkID & 0x7F) );
  339.  
  340.     return( IFF_OKAY );
  341. }
  342.